package com.tuniu.agents.tools.train.tool;

import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.tuniu.agents.message.ToolLogger;
import com.tuniu.agents.message.ToolLoggerInfo;
import com.tuniu.agents.tool.EnvRequest;
import com.tuniu.agents.tools.train.TrainProperties;
import com.tuniu.agents.util.HttpManager;
import com.tuniu.agents.util.JsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.model.ToolContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

import static com.tuniu.agents.tools.train.TrainProperties.KEY_NAME;

/**
 * Query train tickets based on time range (Including: direct, same-train seat transfer, multiple segments)
 */
public class SearchConditionTrainTool implements BiFunction<SearchConditionTrainTool.Request, ToolContext, SearchAllTrainTool.Response> {

    private static final Logger logger = LoggerFactory.getLogger(SearchConditionTrainTool.class);

    public static final String TOOLNAME = "search_condition_train";

    private final String searchConditionTrainUrl;

    private final String accessKey;

    @Autowired
    private HttpManager httpManager;

    public SearchConditionTrainTool(TrainProperties properties) {
        this.searchConditionTrainUrl = properties.getSearchConditionTrainUrl();
        this.accessKey = properties.getAccessKey();
    }

    @Override
    @ToolLoggerInfo(beanName = "trainToolLoggingService")
    public SearchAllTrainTool.Response apply(@EnvRequest SearchConditionTrainTool.Request request, ToolContext toolContext) {
        String conversationId = (String)toolContext.getContext().get("conversation_id");
        logger.info("SearchConditionTrainTool apply conversationId:{}, request:{}",conversationId,JsonUtil.toJson(request));

        try {
            SearchAllTrainTool.Response response = httpManager.post(searchConditionTrainUrl, request, SearchAllTrainTool.Response.class, Map.of(KEY_NAME,accessKey));;
            if(!response.successCode() || CollectionUtils.isEmpty(response.data())){
                logger.error("SearchConditionTrainTool apply fail or empty conversationId:{},request:{},response:{}",conversationId, JsonUtil.toJson(request),JsonUtil.toJson(response));
                return null;
            }
            return response;
        }catch (Exception e){
            logger.error("SearchConditionTrainTool apply error conversationId:{}, request:{}", conversationId, JsonUtil.toJson(request),e);
            return null;
        }
    }

    @JsonClassDescription("Train ticket query parameters with specific time period")
    public record Request(

            @JsonProperty(value = "departureCityName", required = true)
            @JsonPropertyDescription("Departure city or station name, cannot be the same as arrivalCityName")
            String departureCityName,

            @JsonProperty(value = "arrivalCityName", required = true)
            @JsonPropertyDescription("Arrival city or station name, cannot be the same as departureCityName")
            String arrivalCityName,

            @JsonProperty(value = "departureDate", required = true)
            @JsonPropertyDescription("Departure date in yyyy-MM-dd format")
            String departureDate,

            @JsonProperty(value = "departureTime")
            @JsonPropertyDescription("Departure time range, example: for trains departing between 15:00-17:00 (3PM to 5PM), value format: 15:00-17:00")
            String departureTime,

            @JsonProperty(value = "arrivalTime")
            @JsonPropertyDescription("Arrival time range, example: for trains arriving between 12:00-14:00 (12PM to 2PM), value format: 12:00-14:00")
            String arrivalTime
    ) {}

}
